package com.cqjtu.tto.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqjtu.tto.dao.mapper.*;
import com.cqjtu.tto.dao.pojo.Role;
import com.cqjtu.tto.dao.pojo.Salary;
import com.cqjtu.tto.dao.pojo.SysUser;
import com.cqjtu.tto.dao.pojo.SysUserRole;
import com.cqjtu.tto.service.RoleService;
import com.cqjtu.tto.service.SalaryService;
import com.cqjtu.tto.service.SysUserService;
import com.cqjtu.tto.vo.Results;
import com.cqjtu.tto.vo.SalaryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 工资 服务实现类
 * </p>
 *
 * @author MrLuo
 * @since 2021-12-14
 */
@Service
public class SalaryServiceImpl extends ServiceImpl<SalaryMapper, Salary> implements SalaryService {
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SalaryMapper salaryMapper;
    @Autowired
    private TaskMapper taskMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    /**
     * 每个月15日自动生成员工工资
     * 最终工资=基本工资+达标工资（基本工资*10%）
     * 1.先获取公司的全部员工
     * 2.获取公司的角色（包含了角色的考核标准）
     * 3.获取每个员工从上个月15日到当前完成的任务数量
     * 4.生成每个员工的工资
     * 5.插入工资
     */
    @Scheduled(cron = "0 0 0 15 * ?")   // 每月的15日0时0分0秒触发 cron = "0 0 0 15 * ?"
    @Override
    public void createEmployeeSalary() {
        // 获取公司角色
        List<Role> roles = roleMapper.selectList(new LambdaQueryWrapper<Role>().eq(Role::getRoleDeleted, 0));
        Map<String, BigDecimal> map = new HashMap<>();
        roles.forEach(role -> {
                    map.put(role.getRoleName(), role.getRoleBaseSalary());
        });
        Map<String, Integer> map1 = new HashMap<>();
        roles.forEach(role -> {
            map1.put(role.getRoleName(), role.getRoleAssessmentIndex());
        });
        // 获取公司全部员工
        List<SysUser> sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().isNotNull(SysUser::getDepartmentId));
        // 当前时间
        LocalDateTime currentDateTime = LocalDateTime.now();
        // 上次结算时间
        LocalDateTime priorDateTime = currentDateTime.plusMonths(-1);
        // 生成员工工资
        List<Salary> salaries = new ArrayList<>();
        sysUsers.forEach(sysUser -> {
            Integer taskCount = taskMapper.getEmployeeCompleteTaskCount(priorDateTime, currentDateTime, sysUser.getUserId());
            Salary salary = new Salary();
            salary.setUserId(sysUser.getUserId());
            salary.setSalaryCreat(currentDateTime);
            // 获取该员工的角色以判断是否达标
            List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectList(
                    new LambdaQueryWrapper<SysUserRole>()
                            .eq(SysUserRole::getUserId, sysUser.getUserId()));
            List<Long> ids = sysUserRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());

            // 通过ids查询角色
            List<Role> roles1 = roleMapper.listRoleByRoleId(ids); // 当前用户的角色
            Set<String> collect = roles1.stream().map(Role::getRoleName).collect(Collectors.toSet());
            // 判断是否是主管之类的
            if (collect.contains("admin")){
                // 管理员
                if (taskCount >= map1.get("admin")){
                    // 达标
                    salary.setBaseSalary(map.get("admin"));
                    salary.setPerformanceSalary(map.get("admin").multiply(new BigDecimal(0.1)));
                }
                else{
                    salary.setBaseSalary(map.get("admin"));
                    salary.setPerformanceSalary(new BigDecimal(0));
                }
            }
            else if (collect.contains(map.get("leader"))){
                // 领导
                if (taskCount >= map1.get("leader")){
                    // 达标
                    salary.setBaseSalary(map.get("leader"));
                    salary.setPerformanceSalary(map.get("leader").multiply(new BigDecimal(0.1)));
                }
                else{
                    salary.setBaseSalary(map.get("leader"));
                    salary.setPerformanceSalary(new BigDecimal(0));
                }
            }
            else if (collect.contains(map.get("skilled-worker"))){
                // 主管
                if (taskCount >= map1.get("skilled-worker")){
                    // 达标
                    salary.setBaseSalary(map.get("skilled-worker"));
                    salary.setPerformanceSalary(map.get("skilled-worker").multiply(new BigDecimal(0.1)));
                }
                else{
                    salary.setBaseSalary(map.get("skilled-worker"));
                    salary.setPerformanceSalary(new BigDecimal(0));
                }
            }
            else{
                if (taskCount>=10){
                    // 达标
                    salary.setBaseSalary(new BigDecimal(4000));
                    salary.setPerformanceSalary(new BigDecimal(400));
                }
                else{
                    salary.setBaseSalary(new BigDecimal(4000));
                    salary.setPerformanceSalary(new BigDecimal(0));
                }
            }
            salaries.add(salary);
        });
        // 插入员工工资
        this.saveBatch(salaries);
    }

    /**
     * 获取全部员工上次的工资情况
     * 1.得到上次员工工资生成时间（上次发工资的时间，上个15日）
     * 2.查询全部员工的上次工资
     * @return
     */
    @Override
    public Results listEmployeeSalary() {
        LocalDate now = LocalDate.now();
        // 获取上次发工资时间
        LocalDate pDate = now.plusMonths(-1 * (now.getDayOfMonth() < 15 ? 1 : 0));
        LocalDate lastDate = LocalDate.of(pDate.getYear(), pDate.getMonth(), 15);
        List<Salary> salaries = salaryMapper.listEmployeeSalary(lastDate);
        List<SysUser> sysUsers = sysUserMapper.selectList(null);
        // 把员工id和员工名映射
        Map<Long, String> map = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getUserName));
        List<SalaryVo> salaryVos = new ArrayList<>();
        salaries.forEach(salary -> {
            salaryVos.add(new SalaryVo(salary,map.get(salary.getUserId())));
        });
        return Results.success(salaryVos);
    }

    /**
     * 通过员工id获取员工全部的工资记录
     * @param sysUserId
     * @return
     */
    @Override
    public Results listEmployeeHistoryByUserId(Long sysUserId) {
        List<Salary> salaries = this.list(new LambdaQueryWrapper<Salary>().eq(Salary::getUserId, sysUserId));
        SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserId, sysUserId));
        List<SalaryVo> salaryVos = new ArrayList<>();
        salaries.forEach(salary -> {
            salaryVos.add(new SalaryVo(salary,sysUser.getUserName()));
        });
        return Results.success(salaryVos);
    }
}
